package com.gridmobi.xrtb.common;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.RateLimiter;
import com.gridmobi.xrtb.domain.dsp.DspCampaigns;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class CampaignRateLimiter {

    public static Map<Long, RateLimiter> C_LIMITER = Maps.newHashMap();
    public static Map<String, RateLimiter> C_LIMITER_SUB = Maps.newHashMap();

    public static void initLimiter(List datas) {
        String qpsgeos = "PHL,VNM,IDN,THA,SGP,MYS,KOR,USA,GBR,DEU,ESP,FRA,MEX,BRA";
        Map<Long, RateLimiter> map = newcLimiter();
        Map<String, RateLimiter> mapsub = newcLimiterSub();
        datas.forEach(n -> {

            DspCampaigns c = JSONObject.parseObject(JSONObject.toJSONString(n), DspCampaigns.class);
            if (c.getBudgetdaily() != null && c.getBudgetdaily() >= 0) {
                Float remainBudget = c.getBudgetdaily() - c.getCurrentdailybudget();
                int h = new Date().getHours();
                int remainH = (24 - h);
                Float times = c.getBudgetdaily() / c.getBuyingprice();

                /*
                1,2
                1^mys,1^sgp,1^phl
                */
                String tc = c.getCfs().get("TARGETING_COUNTRIES");
                if (StringUtils.isBlank(tc)) {
                    tc = qpsgeos;
                }
                String to = c.getTargetingos();
                String[] toa = to.split("[, \n]");
                String[] tca = tc.split("[, \n]");

                int tolen = toa.length;
                int tclen = tca.length;

                Float rateS = ((times * 1000 * 20) / (24 * 60 * 60));
                int x = tolen * tclen;

                rateS = rateS / x;
                Float finalRateS = rateS;
                Arrays.stream(toa).forEach(os -> {
                    Arrays.stream(tca).forEach(geo -> {
                        String limitkey = c.getId() + geo + os;
                        System.out.println("Limit :" + limitkey + " " + c.getBudgetdaily() + " " + finalRateS);
                        mapsub.put(limitkey, RateLimiter.create(finalRateS));
                    });
                });
                map.put(c.getId(), RateLimiter.create(rateS));

                System.out.println("Limit :" + c.getId() + " " + c.getBudgetdaily() + " " + rateS);
            } else {
                map.put(c.getId(), RateLimiter.create(0.01));
            }

        });
        setcLimiter(map);
        setcLimiterSub(mapsub);

    }


    public static Map<Long, RateLimiter> getcLimiter() {
        return C_LIMITER;
    }

    public static void setcLimiter(Map<Long, RateLimiter> cLimiter) {
        C_LIMITER = cLimiter;
    }

    public static Map<String, RateLimiter> getcLimiterSub() {
        return C_LIMITER_SUB;
    }

    public static void setcLimiterSub(Map<String, RateLimiter> cLimiterSub) {
        C_LIMITER_SUB = cLimiterSub;
    }

    public static Map<Long, RateLimiter> newcLimiter() {
        Map<Long, RateLimiter> map = Maps.newHashMap();
        return map;
    }

    public static Map<String, RateLimiter> newcLimiterSub() {
        Map<String, RateLimiter> map = Maps.newHashMap();
        return map;
    }


    public static boolean tryAcquire(long cid) {
        return C_LIMITER.get(cid).tryAcquire();
    }


}
